﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.TeamFoundation.VersionControl.Client;

namespace TFSTools.TFSLibrary.VersionControl
{
    public sealed class TFSPendingChange : TFSServerEntity
    {
        private PendingChange serverPendingChange;
        private TFSPendingSet tfsPendingSet;

        internal TFSPendingChange(ITFSConnection connection, PendingChange pendingChange, TFSPendingSet pendingSet)
            : base(connection)
        {
            this.serverPendingChange = pendingChange;
            this.tfsPendingSet = pendingSet;
        }

        internal PendingChange ServerEntity { get { return this.serverPendingChange; } }

        public TFSPendingSet PendingSet { get { return this.tfsPendingSet; } }

        public string FileName { get { return this.serverPendingChange.FileName; } }

        public string ChangeTypeName { get { return this.serverPendingChange.ChangeTypeName; } }

        public DateTime CreationDate { get { return this.serverPendingChange.CreationDate; } }

        public string LocalOrServerFolder { get { return this.serverPendingChange.LocalOrServerFolder; } }

        public string LocalItem { get { return this.serverPendingChange.LocalItem; } }

        public string LockLevelName { get { return this.serverPendingChange.LockLevelName; } }
    }

    public sealed class TFSPendingChangeCollection : TFSServerEntityCollection<TFSPendingChange>
    {
        private TFSPendingSet tfsPendingSet;

        public TFSPendingChangeCollection(TFSPendingSet pendingSet) : base(pendingSet.Connection)
        {
            this.ValidatePendingSet(pendingSet);
        }

        public TFSPendingChangeCollection(TFSPendingSet pendingSet, IList<TFSPendingChange> list)
            : base(pendingSet.Connection, list)
        {
            this.ValidatePendingSet(pendingSet);
        }

        public TFSPendingChangeCollection(TFSPendingSet pendingSet, int capacity)
            : base(pendingSet.Connection, capacity)
        {
            this.ValidatePendingSet(pendingSet);
        }

        private void ValidatePendingSet(TFSPendingSet pendingSet)
        {
            if (pendingSet == null)
            {
                throw new InvalidOperationException("Pending Set must be specified for TFSPendingChangeCollection.");
            }

            this.tfsPendingSet = pendingSet;
        }

        internal static TFSPendingChangeCollection Create(ITFSConnection connection, PendingChange[] sets, TFSPendingSet pendingSet)
        {
            var list = new List<TFSPendingChange>(sets.Length);

            foreach (var set in sets)
            {
                list.Add(new TFSPendingChange(connection, set, pendingSet));
            }

            return new TFSPendingChangeCollection(pendingSet, list);
        }

        public int Undo()
        {
            this.tfsPendingSet.Connection.CheckConnection();

            if (this.Any())
            {
                var workSpace = this.tfsPendingSet.GetWorkSpace();
                return workSpace.ServerEntity.Undo((from entity in this select entity.ServerEntity).ToArray());
            }

            return 0;
        }

        internal override void ValidateEntity(TFSPendingChange entity)
        {
            if (this.tfsPendingSet != null && entity.PendingSet != this.tfsPendingSet)
            {
                throw new InvalidOperationException("This PendingChange does not belong to the Pending Set associated with this collection.");
            }
        }
    }
}
